<template>
  <div id="detail">
    <!-- 导航 -->
    <detail-nav-bar ref="navBar" @itemNavImgClick="navImgClick" />

    <!-- 使用better-scroll包裹要局部滚动的组件, TODO: 有轮播图需要监听轮播图加载完成后再计算高度 -->
    <scroll
      class="content"
      :probe-type="3"
      ref="betterScroll"
      @scroll="scrollHandler"
    >
      <!-- 轮播图 -->
      <detail-swiper :top-swiper="topSwiper" />

      <!-- 商品基本信息展示 -->
      <detail-base-info :base-info="goodsInfo" />

      <!-- 商家基本信息展示 -->
      <detail-shop-info :shop-info="shopInfo" />

      <!-- 商品详情以及套图 -->
      <detail-goods-info
        :goods-info="goodsDetailInfo"
        @goodsImgLoad="shopLoad"
      />

      <!-- 商品参数 -->
      <detail-params-info ref="params" :paramsInfo="goodsParams" />

      <!-- 用户评价 -->
      <detail-rate-info ref="review" :user-rate-info="userReviewInfo" />

      <!-- 推荐模块 -->
      <detail-recommend-info ref="recommend" :recommend-list="recommendList" />
    </scroll>

    <!-- 加入购物车组件 -->
    <detail-bottom-bar @addCart="addCartHandler" />

    <!-- 返回顶部 -->
    <!-- TODO: 当监听组件的原生事件时需要使用 .native修饰符 -->
    <back-top @click.native="backHandler" v-show="isBackTopShow" />
  </div>
</template>

<script>
import DetailNavBar from './childrenComponents/DetailNavBar.vue'
import DetailSwiper from './childrenComponents/DetailSwiper.vue'
import DetailBaseInfo from './childrenComponents/DetailBaseInfo.vue'
import DetailShopInfo from './childrenComponents/DetailShopInfo.vue'
import DetailGoodsInfo from './childrenComponents/DetailGoodsInfo.vue'
import DetailParamsInfo from './childrenComponents/DetailParamsInfo.vue'
import DetailRateInfo from './childrenComponents/DetailRateInfo.vue'
import DetailRecommendInfo from './childrenComponents/DetailRecommendInfo.vue'
import DetailBottomBar from './childrenComponents/DetailBottomBar.vue'

// 滚动组件
import Scroll from 'components/common/Scroll/Scroll.vue'

// 网络请求
import {
  getDetail,
  getRecommend,
  GoodsInfo,
  Shop,
  DetailInfo,
  GoodsParams,
  UserReview
} from 'network/detail'

// 调用工具函数
import { itemListMixin, backTopMixin } from 'utils/mixin'

// Actions 辅助函数, 在methods中使用
import { mapActions } from 'vuex'

export default {
  name: 'Detail',
  props: {},
  data () {
    return {
      // 商品ID
      goodsId: null,
      // 轮播图
      topSwiper: [],
      // 商品信息
      goodsInfo: {},
      // 商家信息
      shopInfo: {},
      // 商品套图
      goodsDetailInfo: {},
      // 商品参数
      goodsParams: {},
      // 用户信息/评价
      userReviewInfo: {},
      // 推荐商品数据
      recommendList: [],
      // 电梯导航数据
      themeTopY: [],
      // 当前滚动到的主题区域的索引
      currentIndex: 0,
      timer: null
    }
  },
  created () {
    // 1-TODO: 保存传递过来商品id
    this.goodsId = this.$route.params.id // 动态方式的传递的iid, 传递单个数据
    // this.goodsId = this.$route.query.id // query方式传递参数, 传递多个数据

    // 2-TODO: 根据id向服务器请求数据
    getDetail(this.goodsId).then((res) => {
      const data = res.result
      // console.log(data)
      // TODO: ①-获取顶部录播图数据
      this.topSwiper = data.itemInfo.topImages

      // TODO: ②-获取商品信息 (将需要的信息整合到一个类中)
      this.goodsInfo = new GoodsInfo(
        data.itemInfo,
        data.columns,
        data.shopInfo.services
      )

      // TODO: ③-获取商家信息
      this.shopInfo = new Shop(data.shopInfo)

      // TODO: ④-获取商品的详情和套图
      this.goodsDetailInfo = new DetailInfo(data.detailInfo)

      // TODO: ⑤-获取商品的参数
      this.goodsParams = new GoodsParams(
        data.itemParams.info,
        data.itemParams.rule
      )

      // TODO: ⑥-获取用户评价
      this.userReviewInfo = new UserReview(
        data.rate.list ? data.rate.list[0] : {}
      )

      // 在这里获取位置, 使用$nextTick, 在下一次DOM渲染完毕后立即执行回调函数中的代码
      // 虽然dom已经渲染出来了, 但是图片依然没有加载完, 我们所获取的位置是不对的
      // this.$nextTick(() => {
      //   this.themeTopY.push(0) // 商品位置
      //   this.themeTopY.push(this.$refs.params.$el.offsetTop) // 参数位置
      //   this.themeTopY.push(this.$refs.review.$el.offsetTop) // 评论位置
      //   this.themeTopY.push(this.$refs.recommend.$el.offsetTop) // 推荐位置

      //   console.log(this.themeTopY)
      // })
    })

    // 3-TODO: 请求推荐模块数据
    getRecommend().then((res) => {
      // console.log(res.data.list)
      this.recommendList = res.data.list
    })
  },
  mounted () {},
  // 混入
  mixins: [itemListMixin, backTopMixin],
  updated () {},
  destroyed () {
    // 在组件销毁时, 解绑全局事件
    this.$bus.$off('itemImgLoad', this.itemImglistener)
  },
  computed: {},
  methods: {
    ...mapActions({ add: 'addCart' }),

    // 重新计算滚动高度
    shopLoad () {
      // 只有当所有的图片都加载完毕后,才可以重新计算滚动高度
      // 第一种方式： 计算 counter 和数组的长度是否相等
      this.$refs.betterScroll.refresh()

      // 第二种方式: 混入防抖: 还是使用第一种方式
      // this.newRefresh()
      // console.log('所有图片加载完毕')

      // TODO: 在所有图片都加载完毕之后,获取相应组件的位置
      this.themeTopY.push(0) // 商品位置
      this.themeTopY.push(this.$refs.params.$el.offsetTop - 44) // 参数位置
      this.themeTopY.push(this.$refs.review.$el.offsetTop - 44) // 评论位置
      this.themeTopY.push(this.$refs.recommend.$el.offsetTop - 44) // 推荐位置
      // 第二种方式: 再往后添加一个最大值, 形成区间判断 number.MAX_VALUE
      this.themeTopY.push(Number.MAX_VALUE)

      // console.log(this.themeTopY)
    },
    navImgClick (idx) {
      // 点击后进行跳转
      this.$refs.betterScroll.scrollTo(0, -this.themeTopY[idx])
    },
    // 滚动到某个区域后, 导航栏标签对应进行跳转
    scrollHandler (position) {
      const positionY = Math.abs(position.y)

      // [0, 6138, 6931, 7141]
      // 当positionY的值在0~6138之间时, index = 0
      // 当positionY的值在6138~6931之间时, index = 1
      // 当positionY的值在6931~7141之间时, index = 2
      // 当positionY的值在 >= 7141时, index = 3

      // console.log(positionY)
      // TODO: 第一种做法:循环数组 (有点难以辨识的代码, 多条件判断让人眼晕)
      let length = this.themeTopY.length

      // for (let i = 0; i < length; i++) {
      //   // 第一种
      //   if (this.currentIndex !== i && ((i < length - 1 && positionY >= this.themeTopY[i] && positionY < this.themeTopY[i + 1]) || (i === length - 1 && positionY >= this.themeTopY[i]))) {
      //     // 将滚动区域对应的索引, 保存起来
      //     this.currentIndex = i
      //     // 传递给nav组件
      //     this.$refs.navBar.currentIndex = this.currentIndex
      //   }
      // }

      // 第二种: 简化写法
      for (let i = 0; i < length - 1; i++) {
        // 防止下标越界 0 1 2 3 4(划掉)
        if (
          this.currentIndex !== i &&
          positionY >= this.themeTopY[i] &&
          positionY < this.themeTopY[i + 1]
        ) {
          // 将下标保存起来
          this.currentIndex = i
          // 传递给nav组件
          this.$refs.navBar.currentIndex = this.currentIndex
        }
      }

      // 滚动的时候是否显示返回顶部按钮
      this.showBackTopBtn(positionY)
    },
    // 添加到购物车
    addCartHandler () {
      // 1-获取购物车页面需要展示的信息
      const goods = {}
      goods.iid = this.goodsId
      goods.image = this.topSwiper[0]
      goods.title = this.goodsInfo.title
      goods.desc = this.goodsInfo.desc
      goods.price = this.goodsInfo.nowPrice
      // 将商品传递到vuex中
      // this.$store.state.cartGoodsList.push(goods) // 错误做法, 不能直接修改

      // 正确做法: dispatch可以返回一个promise
      // 不使用辅助函数调用
      // this.$store.dispatch('addCart', goods).then(res => {
      //   console.log(res)
      // })

      // 使用辅助函数 mapActions
      if (!this.timer) {
        this.timer = true

        this.add(goods).then(res => {
          // console.log(res)
          this.$Toast.show(res, 1500)
        })

        this.timer = setTimeout(() => {
          this.timer = false
        }, 1500)
      }
    }
  },
  watch: {},
  components: {
    DetailNavBar,
    DetailSwiper,
    DetailBaseInfo,
    DetailShopInfo,
    Scroll,
    DetailGoodsInfo,
    DetailParamsInfo,
    DetailRateInfo,
    DetailRecommendInfo,
    DetailBottomBar
  }
}
</script>

<style lang="less" scoped>
#detail {
  height: 100%;

  .content {
    // 这里计算高度 还要加 上 bottomBar的49px
    height: calc(100vh - 93px);
    overflow: hidden;
  }

    /* 媒体查询 */
  @media screen and (min-width: 319px) and (max-width: 374px) {
    .content {
      height: calc(100vh - 87px);
    }
  }
}
</style>
